<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>判断类型的终极解决方案</title>
</head>
<body>
  <script>
    // 无论typeof 还是instanceof 都有弊端，并不能满足所有场景的需求
    // 如果需要通过检测数据类型，可以采用Object.prototype.toString,调用该方法，统一返回格式“[object Xxx]”的字符串
    Object.prototype.toString({}) // "[object Object]"
    Object.prototype.toString.call({}) // 结果同上，加上call也ok
    Object.prototype.toString.call(1) // "[object Number]"
    Object.prototype.toString.call('1') // "[object String]"
    Object.prototype.toString.call(true) // "[object Boolean]"
    Object.prototype.toString.call(function() {})// "[object Function]"
    Object.prototype.toString.call(null) // "[object Null]"
    Object.prototype.toString.call(undefined) // "[object Undefined]"
    Object.prototype.toString.call(/123/g) // "[object RegExp]"
    Object.prototype.toString.call(new Date()) // "[object Date]"
    Object.prototype.toString.call([]) // "[object Array]"
    Object.prototype.toString.call(document) // "[object HTMLDocument]"
    Object.prototype.toString.call(window) // "[object Window]"
    // 了解了toString的基本用法，下面就实现一个全局通用的数据类型判断方法
    function getType(obj) {
      let type = typeof obj
      if (type !== 'object') { // 先进行typeof判断，如果是基础数据类型，直接返回
        return type
      }
      // 对于typeof返回是object的，再进行如下的判断，正则返回结果
      return Object.prototype.toString.call(obj).replace(/^\[object(\s+)\]$/, '$1')
    }
    // 使用如下，
    getType([])// Array typeof [] 是object
    getType('123')
    getType(window)
    getType(null)
    getType(undefined)
    getType()
    getType(function() {})
    getType(/123/g)


  </script>
</body>
</html>